{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Hello, QPanda\n",
    "---\n",
    "Welcome you to QPanda!\n",
    "\n",
    "QPanda is a *Quantum Programming Environment* for realistic quantum computers. The project is meant to set up an programming environment to make use of the quantum accelerator (a.k.a. quantum computer).\n",
    "\n",
    "QPanda is mainly written in C++, and pyQPanda is its Python wrapper. Before getting started, you have to read Readme/Installation first to install the QPanda system on your computer.\n",
    "\n",
    "## Getting Started\n",
    "---\n",
    "The main functionalites are distributed in pyQPanda. That includes:\n",
    "\n",
    " - pyqpanda: essential API for users\n",
    " - pyqpanda.utils: extended API\n",
    " - pyqpanda.Algorithm: algorithm pack\n",
    " - pyqpanda.Hamiltonian: representation of Hamiltonian\n",
    " \n",
    "Trying to import pyqpanda is the way to  your installation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# import QPanda python wrapper & extension APIs\n",
    "\n",
    "from pyqpanda import *\n",
    "from pyqpanda.utils import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "init() and finalize() are the way to maintain the runtime enviroment and context.\n",
    "\n",
    "Calling init() is necessary before doing anything about quantum computer. And by calling finalize(), all calculated data will be removed, and anything done with quantum computer is unavailable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# start everything from init()\n",
    "init()\n",
    "\n",
    "# after you finish your work\n",
    "finalize()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preparation of quantum states, then readout\n",
    "---\n",
    "Three main steps have to be taken running a quantum program.\n",
    "\n",
    "    1. Allocate resources (qubits/cbits)\n",
    "    2. Make the quantum program\n",
    "    3. Run and fetch result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'1': 53, '0': 47}\n"
     ]
    }
   ],
   "source": [
    "init()\n",
    "\n",
    "# allocate qubits and cbits\n",
    "\n",
    "q=qAlloc()\n",
    "c=cAlloc()\n",
    "\n",
    "# Create an empty program and insert quantum operations\n",
    "prog=QProg()\n",
    "prog.insert(H(q)) \\\n",
    "    .insert(Measure(q,c))\n",
    "\n",
    "# Run with configuration and fetch result\n",
    "result=run_with_configuration(program=prog, shots=100,cbit_list={c})\n",
    "\n",
    "# finally print the result\n",
    "print(result)\n",
    "\n",
    "finalize()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Brief explanation\n",
    "\n",
    "A Hadamard gate acts on a qubit creating a superpostion state, which is like:\n",
    "\n",
    "$$H|0\\rangle \\rightarrow \\frac{1}{\\sqrt{2}}(|0\\rangle+|1\\rangle)$$\n",
    "\n",
    "By measuring the output state, there is an equal probabilites on the both 0 and 1 result.\n",
    "\n",
    "The Measure(q,c) measures the qubit \"q\" and then maps the result to the classical bit \"c\".\n",
    "\n",
    "In run_with_configuration, \"shots\" is the times of repetition run, and the \"cbit_list\" is the classical register you care about.\n",
    "\n",
    "You will find that each time you run the upper block, you will get different result: that's QUANTUM!\n",
    "\n",
    "## Other examples: with 2 and more qubits\n",
    "\n",
    "If you want to allocate more qubits, you can call \"qAlloc_many\" with the qubits count. The return value is a list of qubits. And so does the cbits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'11': 40, '00': 60}\n"
     ]
    }
   ],
   "source": [
    "init()\n",
    "\n",
    "q=qAlloc_many(2)\n",
    "c=cAlloc_many(2)\n",
    "\n",
    "prog=QProg()\n",
    "prog.insert(H(q[0])) \\\n",
    "    .insert(CNOT(q[0],q[1])) \\\n",
    "    .insert(meas_all(q[0:2],c[0:2]))\n",
    "\n",
    "result=run_with_configuration(program=prog, shots=100,cbit_list=c[0:2])\n",
    "\n",
    "print(result)\n",
    "\n",
    "finalize()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Brief explanation\n",
    "\n",
    "Here we make an entanglement state on 2 qubits, which we call \"Bell state\" or \"Cat State\", which is like:\n",
    "|\n",
    "$$ \\text{CNOT}_{0,1}\\text{H}_0|0\\rangle \\rightarrow \\frac{1}{\\sqrt{2}}(|00\\rangle+|11\\rangle) $$\n",
    "\n",
    "Subscript is used to mark the operation qubit index. $\\text{CNOT}_{0,1}$ means qubit 0 is the controller and 1 is the target.\n",
    "\n",
    "When measuring these two qubits, they perform the identical behaviour - one is 0 and another is 0, one is 1 and another is 1.\n",
    "\n",
    "\"meas_all\" is the way we map many qubits onto many bits with their measurements result."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
